package Dungeon;

/**
 * 
 */


import static org.junit.Assert.*;


import java.math.BigDecimal;
import java.util.ArrayList;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

import squarePackage.RockSquare;
import squarePackage.Square;
import squarePackage.PlainSquare;
import squarePackage.SquareImp;
import squarePackage.TeleportPlainSquare;
import squarePackage.TeleportTransparantSquare;
import squarePackage.TransparantSquare;
import Enumerations.Directions;
import Enumerations.Temperature;
import Exceptions.IllegalDimensionException;
import Obstacle.Door;
import Obstacle.Wall;

/**
 * @author Pieter
 * 
 */
public class DungeonTest {

	/**
	 * @throws java.lang.Exception
	 */
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}

	/**
	 * @throws java.lang.Exception
	 */
	@AfterClass
	public static void tearDownAfterClass() throws Exception {
	}

	Level<SquareImp> Level;
	/**
	 * @throws java.lang.Exception
	 */
	@Before
	public void setUp() throws Exception {
		Level = new Level<SquareImp>(10, 10, 10,8);
		PlainSquare firstSquare = new PlainSquare(10, new BigDecimal("0.3"), null);
		PlainSquare secondSquare = new PlainSquare(0, new BigDecimal("0.4"), null);
		PlainSquare thirdSquare = new PlainSquare(20, new BigDecimal("0.2"), null);
		PlainSquare fourthSquare = new PlainSquare(80, new BigDecimal("0.15"), null);
		PlainSquare fifthSquare = new PlainSquare(30, new BigDecimal("0.17"), null);
		PlainSquare sixthSquare = new PlainSquare(79, new BigDecimal("0.30"), null);
		PlainSquare seventhSquare =new PlainSquare(63, new BigDecimal("0.75"), null);
		PlainSquare eightSquare = new PlainSquare(77, new BigDecimal("0.76"), null);
		PlainSquare ninethSquare = new PlainSquare(100, new BigDecimal("0.47"), null);
		ninethSquare.setMaterial(false);
		eightSquare.setMaterial(false);
		seventhSquare.setMaterial(false);
		firstSquare.setMaterial(false);
		secondSquare.setMaterial(false);
		thirdSquare.setMaterial(false);
		fourthSquare.setMaterial(false);
		fifthSquare.setMaterial(false);
		sixthSquare.setMaterial(false);
		seventhSquare.setMaterial(false);
		eightSquare.setMaterial(false);
		ninethSquare.setMaterial(false);
		Level.addSquareToDungeon(1, 8, 8, firstSquare);
		Level.addSquareToDungeon(1, 6, 8, secondSquare);
		Level.addSquareToDungeon(10, 2, 8, thirdSquare);
		Level.addSquareToDungeon(3, 1, 8, fourthSquare);
		Level.addSquareToDungeon(4, 1, 8, fifthSquare);
		Level.addSquareToDungeon(5, 1, 8, sixthSquare);
		Level.addSquareToDungeon(6,1,8, seventhSquare);
		Level.addSquareToDungeon(7, 1, 8, eightSquare);
		Level.addSquareToDungeon(8, 1, 8, ninethSquare);
	}

	/**
	 * @throws java.lang.Exception
	 */
	@After
	public void tearDown() throws Exception {
	}
	
	
	

	@Test
	public final void firstConstructorLegal() throws IllegalDimensionException {
		Level<SquareImp> Level = new Level<SquareImp>(10, 10, 10,0);
		assertEquals(10, Level.getX());
		assertEquals(10, Level.getY());
		assertEquals(10, Level.getZ());
	}

	@Test
	public final void isValidMaximumDimensionlegalLimit() throws IllegalDimensionException {
		Level<SquareImp> Level = new Level<SquareImp>(10, 10, 10,0);
		assertTrue(Level.isValidMaximumDimensionValue(Long.MAX_VALUE, Level.getX()));

	}

	@Test
	public final void isValidMaximumDimensionlegal() throws IllegalDimensionException {
		Level<SquareImp> Level = new Level<SquareImp>(10, 10, 10,0);
		assertTrue(Level.isValidMaximumDimensionValue(100, Level.getX()));
	}

	

	@Test
	public final void isValidMaximumDimensionilllegal() {
		assertFalse(Level.isValidMaximumDimensionValue(-10,Level.getX()));
	}

	@Test
	public final void isValidMaximumDimensionilllegalOverLimit() {
		assertFalse(Level.isValidMaximumDimensionValue(Long.MAX_VALUE + 1,Level.getX()));
	}

	@Test
	public final void isValidDimensioncheck() {
		assertTrue(Level.isValidDimension(10,Level.getX()));
	}

	@Test
	public final void isValidDimensionXcheckIllegal() throws IllegalDimensionException {
		Level<SquareImp> Level = new Level<SquareImp>(10, 10, 10,0);
		assertFalse(Level.isValidDimension(20, Level.getX()));
	}

	@Test
	public final void setXLegal() throws Exception {
		Level<SquareImp> Level = new Level<SquareImp>(10, 10, 10,0);
		Level.setX(10);
		assertEquals(10, Level.getX());
	}

	@Test(expected = Exception.class)
	public final void setXIllegallow() throws Exception {
		Level<SquareImp> Level = new Level<SquareImp>(10, 10, 10,0);
		Level.setX(-10);

	}

	@Test(expected = Exception.class)
	public final void setXIllegalHihg() throws Exception {
		Level.setX(Long.MAX_VALUE + 1);

	}

	@Test
	public final void createCoordinateLegal() throws Exception {
		assertEquals("1/1|8", Level.createCoordinate(1, 1, 8));
	}

	@Test(expected = Exception.class)
	public final void createCoordinateIlLegalOne()
			throws Exception {
		Level.createCoordinate(1, 11, 1);
	}

	@Test(expected = Exception.class)
	public final void createCoordinateIlLegalTwo()
			throws Exception {
		Level.createCoordinate(50, 10, 1);
	}

	@Test(expected = Exception.class)
	public final void createCoordinateIlLegalTree()
			throws Exception {
		Level.createCoordinate(50, 10, 30);
	}
	
	@Test(expected = Exception.class)
	public final void createCoordinateIllegalAllDimensionSame() throws Exception{
		Level.createCoordinate(1, 1, 1);
	}

	@Test
	public final void canHaveCoordinateTrue(){
		assertTrue(Level.canHaveAsCoordinate(1, 2, 8));
	}
	
	@Test
	public final void canHaveCoordinateFalseDueToInValidDimensions(){
		assertFalse(Level.canHaveAsCoordinate(10, 15, 2));
		
	}
	@Test	
	public final void canHaveCoordinateFalseDueToDuplicateCoordinate() throws Exception{
		
		Level.addSquareToDungeon(1, 2, 8, new PlainSquare());
		assertFalse(Level.canHaveAsCoordinate(1, 2, 8));
		
			
	}
	
	@Test
	public final void canHaveSquareTrue(){
		PlainSquare square = new PlainSquare();
		square.setMaterial(false);
		assertTrue(Level.canHaveAsSquare(square));
	}
	
	@Test
	public final void canHaveSquareFalseTerminate(){
		PlainSquare square = new PlainSquare();
		square.terminate();
		assertFalse(Level.canHaveAsSquare(square));
	}
	
	@Test
	public final void canHaveSquareFalseNullSquare(){
		assertFalse(Level.canHaveAsSquare(null));
	}
	
	@Test
	public final void canHaveSquareFalseDuplicateSquares() throws Exception{
		PlainSquare square = new PlainSquare();
		Level.addSquareToDungeon(1, 2, 8, square);
		assertFalse((Level.canHaveAsSquare(square)));
		
	}
	
	@Test
	public final void canHaveAsSquareAtCoordinateFalse(){
		assertFalse(Level.canHaveAsSquareAtCoordinate(1, 2, 3, null));
	}
	
	@Test
	public final void canHaveAsSquareAtCoordinateTrue(){
		assertTrue(Level.canHaveAsSquareAtCoordinate(1, 2, 8, new PlainSquare()));
	}
	
	@Test
	public final void canHaveAsSquareAtCoordinateFalseInvalidCoordinate(){
		assertFalse(Level.canHaveAsSquareAtCoordinate(1, 1, 30, new PlainSquare()));
	}
	
	@Test
	public final void canHaveAsSquareAtCoordinateFalseDuplicateCoordinate() throws Exception{
		Level.addSquareToDungeon(1, 2,8 , new PlainSquare());
		assertFalse(Level.canHaveAsSquareAtCoordinate(1, 2, 8, new PlainSquare()));
	}
	
	@Test
	public final void canHaveAsSquareAtCoordinateFalseInvAlidSquare(){
		Level.canHaveAsSquareAtCoordinate(1, 2, 3, null);
	}
	
	@Test
	public final void canHaveAsSquareAtCoordinateFalseDuplicateSquare() throws Exception{
		PlainSquare square = new PlainSquare();
		Level.addSquareToDungeon(1, 2, 8, square);
		assertFalse(Level.canHaveAsSquareAtCoordinate(1, 2, 8, square));
	}
		
	@Test
	public final void addSquareLegal() throws Exception{
		PlainSquare square =  new PlainSquare();
		Level.addSquareToDungeon(1, 2, 8, square);
		assertEquals(square, Level.getSquareAt(1, 2, 8));
		assertTrue(square.hasDungeon());
					
	}
	
	@Test	(expected = Exception.class)
	public final void addSquareLegalDoubleLevel() throws Exception{
		PlainSquare square =  new PlainSquare();
		Level.addSquareToDungeon(1, 2, 3, square);
		assertEquals(square, Level.getSquareAt(1, 2, 3));
		assertTrue(square.hasDungeon());
		Level<PlainSquare> otherLevel = new Level<PlainSquare>(10,20,40,0);
		otherLevel.addSquareToDungeon(1, 5, 7, square);
					
	}
	
	
	@Test	(expected = Exception.class)
	public final void addSquareIlLegalCoordinate() throws Exception{
		PlainSquare square =  new PlainSquare();
		Level.addSquareToDungeon(1, 2, 50, square);
					
	}
	
	@Test	(expected = Exception.class)
	public final void addSquareIlLegalSquare() throws Exception {
		Level.addSquareToDungeon(1, 2, 50, new PlainSquare());
					
	}
	
	@Test	(expected = Exception.class)
	public final void addSquareIlLegalSquareTerminated() throws Exception {
		Square newSquare = new PlainSquare();
		newSquare.terminate();
		Level.addSquareToDungeon(1, 2, 50, new PlainSquare());
		
					
	}
	
	@Test	(expected = Exception.class)
	public final void addSquareIlLegalDuplicteCoordinate() throws Exception{
		PlainSquare square =  new PlainSquare();
		PlainSquare otherSquare = new PlainSquare();
		Level.addSquareToDungeon(1, 2, 3, square);
		Level.addSquareToDungeon(1, 2 ,3 , otherSquare);
	}
	
	@Test	(expected = Exception.class)
	public final void addSquareIlLegalDuplicteSquare() throws Exception{
		PlainSquare square =  new PlainSquare();
		Level.addSquareToDungeon(1, 2, 3, square);
		Level.addSquareToDungeon(1,2,1, square);
	}
	
	@Test
	public final void addSquareIllegalDueToTooManySlipperySquaresAndSquareNotAdded() throws Exception{
		Level.addSquareToDungeon(1, 2, 8, new PlainSquare());
		assertEquals(10, Level.getNbSquares());
		Level.addSquareToDungeon(9, 2, 8, new PlainSquare());
		assertEquals(11, Level.getNbSquares());
		new PlainSquare();
		
		
	}
	
	@Test
	public final void numberOfSquares(){
		assertEquals(9, Level.getNbSquares());
	}
	
	@Test
	public final void numberOfSquaresPlus1() throws Exception{
		Level.addSquareToDungeon(1, 2, 8, new PlainSquare());
		assertEquals(10, Level.getNbSquares());
			
	}

	@Test
	public final void numberOfSquaresAmounOfSlipperySqares() throws Exception {
		Level.addSquareToDungeon(1, 2, 8, new PlainSquare());
		Level.addSquareToDungeon(8, 2, 8, new PlainSquare());
		assertEquals(new BigDecimal("2.00"), Level.getAmountOfSlipperySquares());
	}
	
	@Test
	public final void getSquareAtTest(){
		assertTrue(Level.hasSquareAt(5, 1, 8));
		assertFalse(Level.hasSquareAt(1,7,6));
		
	}
	
	@Test
	public final void hasNeighBourAtTestNorth() throws Exception{
		PlainSquare newSquare = new PlainSquare();
		newSquare.setMaterial(false);
		Level.addSquareToDungeon(1, 1, 8, newSquare);
		PlainSquare otherSquare = new PlainSquare();
		otherSquare.setMaterial(false);
		Level.addSquareToDungeon(1, 2, 8, otherSquare);
		assertTrue(Level.hasNeighbourAt(Directions.North, 1, 2, 8));
	}
	
	@Test
	public final void hasNeighBourAtTestSouth() throws Exception{
		PlainSquare newSquare = new PlainSquare();
		newSquare.setMaterial(false);
		Level.addSquareToDungeon(1, 3, 8, newSquare);
		PlainSquare otherSquare = new PlainSquare();
		otherSquare.setMaterial(false);
		Level.addSquareToDungeon(1, 2, 8, otherSquare);
		assertTrue(Level.hasNeighbourAt(Directions.South, 1, 2, 8));
	}
	
	@Test
	public final void hasNeighBourAtTestSouthFalse() throws Exception{
		PlainSquare newSquare = new PlainSquare();
		newSquare.setMaterial(false);
		Level.addSquareToDungeon(1, 7, 8, newSquare);
		PlainSquare otherSquare = new PlainSquare();
		otherSquare.setMaterial(false);
		Level.addSquareToDungeon(1, 2, 8, otherSquare);
		assertFalse(Level.hasNeighbourAt(Directions.South, 1, 2, 8));
		PlainSquare newSquareX = new PlainSquare();
		newSquareX.setMaterial(false);
		Level.addSquareToDungeon(1, 3, 8, newSquareX);
		assertTrue(Level.hasNeighbourAt(Directions.South, 1, 2, 8));
	}
	
	@Test
	public final void getSquareNeighPositionsBViaDirection() throws Exception{
		PlainSquare newSquare = new PlainSquare();
		newSquare.setMaterial(false);
		Level.addSquareToDungeon(1, 1, 8, newSquare);
		PlainSquare otherSquare = new PlainSquare();
		otherSquare.setMaterial(false);
		Level.addSquareToDungeon(1, 2, 8, otherSquare);
		assertEquals(newSquare, Level.getSquareAtDirection(Directions.North, 1, 2, 8));
	}
	
	@Test
	public final void getSquareNeighBPositionsViaDirectionFalse() throws Exception{
		PlainSquare newSquare = new PlainSquare();
		newSquare.setMaterial(false);
		Level.addSquareToDungeon(1, 3, 8, newSquare);
		PlainSquare otherSquare = new PlainSquare();
		otherSquare.setMaterial(false);
		Level.addSquareToDungeon(1, 2, 8, otherSquare);
		assertEquals(null, Level.getSquareAtDirection(Directions.North, 1, 2, 8));
	}
	
	@Test 
	public final void getSquareAtTestLegal(){
		SquareImp squareToGet = Level.getSquareAt(0, 1, 2);
		assertEquals(squareToGet, Level.getSquareAt(0, 1, 2));
		assertEquals(null, Level.getSquareAt(9, 8, 7));
	}
	

	
	@Test
	public final void borderSettingForSquaresBothWalls(){
		
		PlainSquare square = new PlainSquare();
		PlainSquare	neigboor = new PlainSquare();
		
		square.setBorder(Directions.North, new Wall());
		neigboor.setBorder(Directions.South, new Wall());
		square.setMaterial(false);
		neigboor.setMaterial(false);
		
		try {
			Level.addSquareToDungeon(1, 1, 8, neigboor);
			Level.addSquareToDungeon(1, 2, 8, square);
		} catch (IllegalArgumentException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		} catch (IllegalDimensionException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
		}
		
		assertEquals(neigboor.getBorderByDirection(Directions.South), square.getBorderByDirection(Directions.North));
		
		
		
	}
	
	
	
	@Test
	public final void testforCheckingIfSquareCanBeAddedWithConflictingBorders(){
		PlainSquare plain1 = new PlainSquare();
		PlainSquare neigboor = new PlainSquare();
		
		assertEquals(Level.preferencedWall(plain1, neigboor, Directions.North, Directions.South), null);
		
		plain1.setBorder(Directions.North, new Wall());
		
		assertEquals(Level.preferencedWall(plain1, neigboor, Directions.North, Directions.South), plain1.getBorderByDirection(Directions.North));
		
		plain1.deleteBorder(Directions.North);
		
		neigboor.setBorder(Directions.South, new Wall());
		
		assertEquals(Level.preferencedWall(plain1, neigboor, Directions.North, Directions.South), neigboor.getBorderByDirection(Directions.South));
		
	}
	
	@Test
	public final void testforCheckingIfSquareCanBeAddedWithConflictingBorders_case2(){
		PlainSquare square = new PlainSquare();
		PlainSquare neigboor = new PlainSquare();
		
		square.setBorder(Directions.North, new Wall(new Door()));
		neigboor.setBorder(Directions.South, new Wall());
		
		assertEquals(Level.preferencedWall(square, neigboor, Directions.North, Directions.South), neigboor.getBorderByDirection(Directions.South));
		
		neigboor.setBorder(Directions.South, new Wall(new Door()));
		assertTrue(neigboor.getBorderByDirection(Directions.South).hasDoor());
		neigboor.getBorderByDirection(Directions.South).getDoor().openDoor();
		assertTrue(neigboor.getBorderByDirection(Directions.South).getDoor().isOpen());
		
		assertEquals(Level.preferencedWall(square, neigboor, Directions.North, Directions.South), square.getBorderByDirection(Directions.North));
		
		
	}
	
	@Test
	public final void checkAllBordersTest(){
		PlainSquare square = new PlainSquare();
		square.setBorder(Directions.West, new Wall());
		square.setBorder(Directions.North, new Wall(new Door()));
		square.setBorder(Directions.South, new Wall(new Door()));
		
		
		TransparantSquare north = new TransparantSquare();
		PlainSquare south = new PlainSquare();
		south.setBorder(Directions.South, new Wall(new Door()));
		south.setBorder(Directions.East, new Wall(new Door()));
		PlainSquare east = new PlainSquare();
		east.setBorder(Directions.West, new Wall());
		TransparantSquare west = new TransparantSquare();
		square.setMaterial(false);
		north.setMaterial(false);
		east.setMaterial(false);
		west.setMaterial(false);
		south.setMaterial(false);
		
		try {
			Level.addSquareToDungeon(1, 0, 8, north);
			Level.addSquareToDungeon(1, 2, 8, south);
			Level.addSquareToDungeon(0, 1, 8, west);
			Level.addSquareToDungeon(2, 1, 8, east);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalDimensionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertFalse(Level.checkAllBorders(square, 1, 1, 8));
		
		square.deleteBorder(Directions.West);
		
		assertTrue(Level.checkAllBorders(square, 1, 1, 8));
		
		assertTrue(Level.canHaveAsSquareAtCoordinate(1, 1, 8, square));
		
	}
	
	@Test
	public final void addSquareTestNewVersionOfBorders(){
		PlainSquare square = new PlainSquare();
		square.setBorder(Directions.North, new Wall(new Door()));
		square.setBorder(Directions.South, new Wall(new Door()));
		
		
		TransparantSquare north = new TransparantSquare();
		PlainSquare south = new PlainSquare();
		south.setBorder(Directions.South, new Wall(new Door()));
		south.setBorder(Directions.East, new Wall(new Door()));
		PlainSquare east = new PlainSquare();
		east.setBorder(Directions.West, new Wall());
		TransparantSquare west = new TransparantSquare();
		
		square.setMaterial(false);
		north.setMaterial(false);
		east.setMaterial(false);
		west.setMaterial(false);
		south.setMaterial(false);
		
		
		try {
			Level.addSquareToDungeon(1, 0, 8, north);
			Level.addSquareToDungeon(1, 2, 8, south);
			Level.addSquareToDungeon(0, 1, 8, west);
			Level.addSquareToDungeon(2, 1, 8, east);
			Level.addSquareToDungeon(1, 1, 8, square);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IllegalDimensionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertEquals(Level.getSquareAt(1, 1, 8), square);
		
		assertEquals(null, west.getBorderByDirection(Directions.East));
		assertEquals(square.getBorderByDirection(Directions.West), null);
				
		assertEquals(square.getBorderByDirection(Directions.North), north.getBorderByDirection(Directions.South));
		
		assertEquals(square.getBorderByDirection(Directions.East), east.getBorderByDirection(Directions.West));
		
		assertEquals(square.getBorderByDirection(Directions.South), south.getBorderByDirection(Directions.North));
		
		assertEquals(square.getBorderByDirection(Directions.West), west.getBorderByDirection(Directions.East));
		
		
	
	}
	

	
	@Test
	public final void getSquareAtDirectionTest(){
		
		PlainSquare firstSquare = new PlainSquare();
		firstSquare.setMaterial(false);
				
		PlainSquare neighboor = new PlainSquare();
		neighboor.setMaterial(false);
		
		try {
			Level.addSquareToDungeon(1, 4, 8, firstSquare);
			Level.addSquareToDungeon(1, 3, 8, neighboor);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertEquals(firstSquare, Level.getSquareAt(1, 4, 8));
		assertEquals(neighboor, Level.getSquareAt(1, 3, 8));
		
		
		assertEquals(neighboor, Level.getSquareAtDirection(Directions.North, 1, 4, 8));
		
	}
	
	@Test
	public final void getSquareAtDirectionTestNullSquare(){
		
		PlainSquare firstSquare = new PlainSquare();
		firstSquare.setMaterial(false);
				
		PlainSquare neighboor = new PlainSquare();
		neighboor.setMaterial(false);
		
		try {
			Level.addSquareToDungeon(1, 4, 8, firstSquare);
			Level.addSquareToDungeon(1, 3, 8, neighboor);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertEquals(firstSquare, Level.getSquareAt(1, 4, 8));
		assertEquals(neighboor, Level.getSquareAt(1, 3, 8));
		
		
		assertEquals(null, Level.getSquareAtDirection(Directions.South, 1, 4, 8));
		
	}
	
	@Test
	public final void getBorderInDirectionTestTrueWall(){
		PlainSquare firstSquare = new PlainSquare();
		Wall squareWall = new Wall();
		firstSquare.setMaterial(false);
		firstSquare.setBorder(Directions.North, squareWall);
		assertEquals(squareWall, Level.getBorderInDirection(firstSquare, Directions.North));
	
	}
	
	@Test
	public final void getBorderInDirectionTestNullWall(){
		PlainSquare firstSquare = new PlainSquare();
		firstSquare.setBorder(Directions.North, null);
		assertEquals(null, Level.getBorderInDirection(firstSquare, Directions.North));
	}
	
	

	
	
	@Test
	public final void setBordersForSquareAndNeighborLegalTestDifferentDirections(){
		
		PlainSquare firstSquare = new PlainSquare();
		Wall wall = new Wall();
		firstSquare.setMaterial(false);
		firstSquare.setBorder(Directions.South, wall);
		
		
		PlainSquare neighboor = new PlainSquare();
		neighboor.setMaterial(false);
		
				
		try {
			Level.addSquareToDungeon(1, 4, 8, firstSquare);
			Level.addSquareToDungeon(1, 5, 8, neighboor);
			assertEquals(firstSquare, Level.getSquareAt(1, 4, 8));
			assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertTrue(Level.hasNeighbourAt(Directions.South, 1, 4, 8));
		assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
		
		
		assertEquals(firstSquare.getBorderByDirection(Directions.South), wall);
		assertEquals(neighboor.getBorderByDirection(Directions.North), firstSquare.getBorderByDirection(Directions.South));
		assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
		assertEquals(neighboor, Level.getSquareAtDirection(Directions.South, 1, 4, 8));
		
	}
	
	@Test
	public final void setBordersForSquareAndNeighborLegalTestDifferentDirectionsOpenDoor_Null(){
		
		PlainSquare firstSquare = new PlainSquare();
		Wall wall = new Wall();
		firstSquare.setMaterial(false);
		wall.setDoor(new Door(true, wall));
		wall.getDoor().openDoor();
		firstSquare.setBorder(Directions.South, wall);
		
		
		PlainSquare neighboor = new PlainSquare();
		neighboor.setMaterial(false);
				
		try {
			Level.addSquareToDungeon(1, 4, 8, firstSquare);
			Level.addSquareToDungeon(1, 5, 8, neighboor);
			assertEquals(firstSquare, Level.getSquareAt(1, 4, 8));
			assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertTrue(Level.hasNeighbourAt(Directions.South, 1, 4, 8));
		assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
		assertEquals(firstSquare.getBorderByDirection(Directions.South), wall);
		assertEquals(neighboor.getBorderByDirection(Directions.North), firstSquare.getBorderByDirection(Directions.South));
		assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
		assertEquals(neighboor, Level.getSquareAtDirection(Directions.South, 1, 4, 8));
		
	}
	
	@Test
	public final void setBordersForSquareAndNeighborLegalTestDifferentDirectionsOpenDoor_NullBordersForSquare(){
		
		PlainSquare firstSquare = new PlainSquare();
		Wall wall = new Wall();
		firstSquare.setMaterial(false);
		wall.setDoor(new Door(true, wall));
		wall.getDoor().openDoor();
		
		
		PlainSquare neighboor = new PlainSquare();
		neighboor.setMaterial(false);
		neighboor.setBorder(Directions.North, wall);
				
		
			try {
				Level.addSquareToDungeon(1, 4, 8, firstSquare);
					Level.addSquareToDungeon(1, 5, 8, neighboor);
				assertEquals(firstSquare, Level.getSquareAt(1, 4, 8));
				assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
			} catch (Exception e) {
				 //TODO Auto-generated catch block
				e.printStackTrace();
			}
		
		assertTrue(Level.hasNeighbourAt(Directions.South, 1, 4, 8));
		assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
		assertEquals(firstSquare.getBorderByDirection(Directions.South), wall);
		assertEquals(neighboor.getBorderByDirection(Directions.North), firstSquare.getBorderByDirection(Directions.South));
		assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
		assertEquals(neighboor, Level.getSquareAtDirection(Directions.South, 1, 4, 8));
	}
	
	@Test
	public final void setBordersForSquareAndNeighborLegalTestDifferentDirectionsOpenDoor_NullBordersForSquare_NoNeighboors(){
		
		PlainSquare firstSquare = new PlainSquare();
		Wall wall = new Wall();
		firstSquare.setMaterial(false);
		wall.setDoor(new Door(true, wall));
		wall.getDoor().openDoor();
		
		
		
		PlainSquare neighboor = new PlainSquare();
		neighboor.setMaterial(false);
		neighboor.setBorder(Directions.North, wall);
				
		
			try {
				Level.addSquareToDungeon(1, 4, 8, firstSquare);
				Level.addSquareToDungeon(1, 5, 8, neighboor);
				assertEquals(firstSquare, Level.getSquareAt(1, 4, 8));
				assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		
		assertTrue(Level.hasNeighbourAt(Directions.South, 1, 4, 8));
		assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
		assertEquals(Level.getBorderInDirection(neighboor, Directions.North), Level.getBorderInDirection(firstSquare, Directions.South));
		assertEquals(firstSquare.getBorderByDirection(Directions.South), wall);
		assertEquals(neighboor.getBorderByDirection(Directions.North), firstSquare.getBorderByDirection(Directions.South));
		assertEquals(neighboor, Level.getSquareAt(1, 5, 8));
		assertEquals(neighboor, Level.getSquareAtDirection(Directions.South, 1, 4, 8));
		firstSquare.deleteBorder(Directions.North);
		assertEquals(firstSquare.getBorderByDirection(Directions.North), null);
		assertEquals(neighboor.getBorderByDirection(Directions.South), null);
	}
	

	
	@Test 	(expected = Exception.class)
	public final void testaddSquareToDungeonIllegalDimension() throws Exception{
		Level.addSquareToDungeon(500, 10, 1, new PlainSquare());
		
	}
	
	@Test 	
	public final void testaddSquareToDungeonSlipperySquare() throws Exception{
		PlainSquare square = new PlainSquare();
		square.setBorder(Directions.North, new Wall());
		
		Level.addSquareToDungeon(0, 2,8, square);
		
		PlainSquare otherSquare = new PlainSquare();
		otherSquare.setMaterial(true);
		
		Level.addSquareToDungeon(0, 1, 8, otherSquare);
		
		assertEquals(square, Level.getSquareAt(0, 2, 8));
		assertEquals(otherSquare, Level.getSquareAtDirection(Directions.North, 0, 2, 8));
		assertEquals(square.getBorderByDirection(Directions.North ),otherSquare.getBorderByDirection(Directions.South));
		PlainSquare anotherSquare = new PlainSquare();
		Wall wall = new Wall();
		wall.setDoor(new Door(true,wall));
		wall.getDoor().openDoor();
		anotherSquare.setBorder(Directions.West, wall);
		assertFalse(Level.canHaveAsSquare(anotherSquare));
				
		assertEquals(square.getBorderByDirection(Directions.East), null);
		
	}
	

	
	@Test
	public final void addBorderSquare(){
		PlainSquare newSquare = new PlainSquare();
		newSquare.setMaterial(false);
		try {
			Level.addSquareToDungeon(4, 5, 8, newSquare);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		assertEquals(newSquare, Level.getSquareAt(4, 5, 8));
		assertEquals(1,newSquare.hasNumberBorders());
		
		Wall wall = new Wall();
		Level.addBorderToSquareInDungeon(newSquare, Directions.North, wall);
		
		assertEquals(wall, Level.getSquareAt(4, 5, 8).getBorderByDirection(Directions.North));
		
		PlainSquare otherSquare = new PlainSquare();
		otherSquare.setMaterial(false);
		try {
			Level.addSquareToDungeon(4, 4, 8, otherSquare);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	@Test
	public final void addBorderSquareFalse(){
		PlainSquare newSquare = new PlainSquare();
		newSquare.setMaterial(false);
		try {
			Level.addSquareToDungeon(4, 5, 8, newSquare);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		assertEquals(newSquare, Level.getSquareAt(4, 5, 8));
		assertEquals(1,newSquare.hasNumberBorders());
		Wall wall = new Wall();
		
		PlainSquare otherSquare = new PlainSquare();
		otherSquare.setMaterial(false);
		try {
			Level.addSquareToDungeon(4, 4, 8, otherSquare);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		Level.addBorderToSquareInDungeon(newSquare, Directions.North, wall);
		assertEquals(null, Level.getSquareAt(4, 5, 8).getBorderByDirection(Directions.North));
				
	}
	
	
	
		
	
		
	@Test
	public final void testRemoveborderFromSquare(){

		PlainSquare s110 = new PlainSquare();
		PlainSquare s120 = new PlainSquare();
		s120.setBorder(Directions.South, new Wall());
		PlainSquare s130= new PlainSquare();
		s130.setBorder(Directions.South, new Wall());
		s130.setBorder(Directions.East, new Wall());
		PlainSquare s150= new PlainSquare();
		s150.setBorder(Directions.North, new Wall());
		s150.setBorder(Directions.East, new Wall());

		PlainSquare s220= new PlainSquare();
		s220.setBorder(Directions.North, new Wall());
		s220.setBorder(Directions.East, new Wall(new Door()));
		s220.getBorderByDirection(Directions.East).getDoor().openDoor();
		assertTrue(s220.getBorderByDirection(Directions.East).hasDoor());
		PlainSquare s230= new PlainSquare();
		PlainSquare s240= new PlainSquare();
		PlainSquare s250= new PlainSquare();
		s250.setBorder(Directions.East, new Wall());
		PlainSquare s330= new PlainSquare();
		PlainSquare s340= new PlainSquare();
		s340.setBorder(Directions.East, new Wall());
		s340.setBorder(Directions.South, new Wall());
		PlainSquare s430= new PlainSquare();
		s430.setBorder(Directions.North, new Wall());
		s430.setBorder(Directions.East, new Wall());
		s430.setBorder(Directions.South, new Wall(new Door()));
		s430.getBorderByDirection(Directions.South).getDoor().openDoor();
		PlainSquare s440= new PlainSquare();
		s440.setBorder(Directions.East, new Wall());
		PlainSquare s450= new PlainSquare();
		s450.setBorder(Directions.East, new Wall());
		PlainSquare s350= new PlainSquare();
		PlainSquare s610= new PlainSquare();
		PlainSquare s880 = new PlainSquare();
		s610.setBorder(Directions.West, new Wall());
		s610.setBorder(Directions.East, new Wall());
		s610.setBorder(Directions.South, new Wall(new Door()));
		s610.getBorderByDirection(Directions.South).getDoor().openDoor();
		PlainSquare s620= new PlainSquare();
		s620.setBorder(Directions.West, new Wall());
		s110.setTemperature(10, Temperature.CELCIUS);
		s110.setMaterial(false);
		s120.setMaterial(false);
		s110.setHumidity(new BigDecimal("0.3"));
		s120.setHumidity(new BigDecimal("0.2"));
		s120.setTemperature(10, Temperature.CELCIUS);
		s130.setTemperature(10, Temperature.CELCIUS);
		s130.setMaterial(false);
		s150.setMaterial(false);
		s220.setMaterial(false);
		s230.setMaterial(false);
		s240.setMaterial(false);
		s250.setMaterial(false);
		s330.setMaterial(false);
		s340.setMaterial(false);
		s430.setMaterial(false);
		s440.setMaterial(false);
		s450.setMaterial(false);
		s350.setMaterial(false);
		s610.setTemperature(10, Temperature.CELCIUS);
		s620.setTemperature(20, Temperature.CELCIUS);
		s880.setTemperature(30, Temperature.CELCIUS);
		s880.setMaterial(false);
		
		try {
			Level.addSquareToDungeon(1, 1, 8, s110);
			Level.addSquareToDungeon(1, 3, 8, s130);
			Level.addSquareToDungeon(1, 5, 8, s150);
			Level.addSquareToDungeon(2, 2, 8, s220);
			Level.addSquareToDungeon(2, 3, 8, s230);
			Level.addSquareToDungeon(2, 4, 8, s240);
			Level.addSquareToDungeon(2, 5, 8, s250);
			Level.addSquareToDungeon(3, 3, 8, s330);
			Level.addSquareToDungeon(3, 4, 8, s340);
			Level.addSquareToDungeon(4, 3, 8, s430);
			Level.addSquareToDungeon(4, 4, 8, s440);
			Level.addSquareToDungeon(4, 5, 8, s450);
			Level.addSquareToDungeon(3, 5, 8, s350);
			Level.addSquareToDungeon(6, 2, 8, s620);

		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertFalse(Level.isReachableInTheSameSpace(s250,s150));
		assertTrue(s150.hasBorder(Directions.East));
		assertTrue(s250.hasBorder(Directions.West));
		
		Level.removeBorderFromSquareInDungeon(s150, Directions.East);
		assertFalse(s150.hasBorder(Directions.East));
		assertFalse(s250.hasBorder(Directions.West));
		assertTrue(Level.isReachable(s250,s150));
		
		Level.getSpaceOfSquare(s150);
	}
	
	@Test
	public final void removeSquareTest(){
		PlainSquare s110 = new PlainSquare();
		PlainSquare s120 = new PlainSquare();
		s120.setBorder(Directions.South, new Wall());
		PlainSquare s130= new PlainSquare();
		s130.setBorder(Directions.South, new Wall());
		s130.setBorder(Directions.East, new Wall());
		PlainSquare s150= new PlainSquare();
		s150.setBorder(Directions.North, new Wall());
		s150.setBorder(Directions.East, new Wall());

		PlainSquare s220= new PlainSquare();
		s220.setBorder(Directions.North, new Wall());
		s220.setBorder(Directions.East, new Wall(new Door()));
		s220.getBorderByDirection(Directions.East).getDoor().openDoor();
		assertTrue(s220.getBorderByDirection(Directions.East).hasDoor());
		PlainSquare s230= new PlainSquare();
		PlainSquare s240= new PlainSquare();
		PlainSquare s250= new PlainSquare();
		s250.setBorder(Directions.East, new Wall());
		PlainSquare s330= new PlainSquare();
		PlainSquare s340= new PlainSquare();
		s340.setBorder(Directions.East, new Wall());
		s340.setBorder(Directions.South, new Wall());
		PlainSquare s430= new PlainSquare();
		s430.setBorder(Directions.North, new Wall());
		s430.setBorder(Directions.East, new Wall());
		s430.setBorder(Directions.South, new Wall(new Door()));
		s430.getBorderByDirection(Directions.South).getDoor().openDoor();
		PlainSquare s440= new PlainSquare();
		s440.setBorder(Directions.East, new Wall());
		PlainSquare s450= new PlainSquare();
		s450.setBorder(Directions.East, new Wall());
		PlainSquare s350= new PlainSquare();
		PlainSquare s610= new PlainSquare();
		PlainSquare s880 = new PlainSquare();
		s610.setBorder(Directions.West, new Wall());
		s610.setBorder(Directions.East, new Wall());
		s610.setBorder(Directions.South, new Wall(new Door()));
		s610.getBorderByDirection(Directions.South).getDoor().openDoor();
		PlainSquare s620= new PlainSquare();
		s620.setBorder(Directions.West, new Wall());
		s110.setTemperature(10, Temperature.CELCIUS);
		s110.setHumidity(new BigDecimal("0.3"));
		s120.setHumidity(new BigDecimal("0.2"));
		s120.setTemperature(10, Temperature.CELCIUS);
		s130.setTemperature(10, Temperature.CELCIUS);
		s130.setMaterial(false);
		s150.setMaterial(false);
		s220.setMaterial(false);
		s230.setMaterial(false);
		s240.setMaterial(false);
		s250.setMaterial(false);
		s330.setMaterial(false);
		s340.setMaterial(false);
		s430.setMaterial(false);
		s440.setMaterial(false);
		s450.setMaterial(false);
		s350.setMaterial(false);
		s110.setMaterial(false);
		s120.setMaterial(false);
		s610.setTemperature(10, Temperature.CELCIUS);
		s620.setTemperature(20, Temperature.CELCIUS);
		s880.setTemperature(30, Temperature.CELCIUS);
		s880.setMaterial(false);
		s110.setMaterial(false);
		s120.setMaterial(false);
		
		
		try {
			Level.addSquareToDungeon(1, 1, 8, s110);
			Level.addSquareToDungeon(1, 2, 8, s120);
			Level.addSquareToDungeon(1, 3, 8, s130);
			Level.addSquareToDungeon(1, 5, 8, s150);
			Level.addSquareToDungeon(2, 2, 8, s220);
			Level.addSquareToDungeon(2, 3, 8, s230);
			Level.addSquareToDungeon(2, 4, 8, s240);
			Level.addSquareToDungeon(2, 5, 8, s250);
			Level.addSquareToDungeon(3, 3, 8, s330);
			Level.addSquareToDungeon(3, 4, 8, s340);
			Level.addSquareToDungeon(4, 3, 8, s430);
			Level.addSquareToDungeon(4, 4, 8, s440);
			Level.addSquareToDungeon(4, 5, 8, s450);
			Level.addSquareToDungeon(3, 5, 8, s350);
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertFalse(Level.canHaveAsCoordinate(3, 4, 0));
		assertFalse(Level.canHaveAsSquareAtCoordinate(3, 4, 0, new PlainSquare()));
		Level.removeSquareFromDungeon(s340);
		assertFalse(Level.hasSquareAt(3, 4, 0));
		assertTrue(s130.hasBorder(Directions.East));
		
		
		
		
	}
	
	@Test
	public final void removeBorderTestAndCheckIfSpaceIsAdjusted(){
		PlainSquare s110 = new PlainSquare();
		PlainSquare s120 = new PlainSquare();
		s120.setBorder(Directions.South, new Wall());
		PlainSquare s130= new PlainSquare();
		s130.setBorder(Directions.South, new Wall());
		s130.setBorder(Directions.East, new Wall());
		PlainSquare s150= new PlainSquare();
		s150.setBorder(Directions.North, new Wall());
		s150.setBorder(Directions.East, new Wall());

		PlainSquare s220= new PlainSquare();
		s220.setBorder(Directions.North, new Wall());
		s220.setBorder(Directions.East, new Wall(new Door()));
		s220.getBorderByDirection(Directions.East).getDoor().openDoor();
		assertTrue(s220.getBorderByDirection(Directions.East).hasDoor());
		PlainSquare s230= new PlainSquare();
		PlainSquare s240= new PlainSquare();
		PlainSquare s250= new PlainSquare();
		s250.setBorder(Directions.East, new Wall());
		PlainSquare s330= new PlainSquare();
		PlainSquare s340= new PlainSquare();
		s340.setBorder(Directions.East, new Wall());
		s340.setBorder(Directions.South, new Wall());
		PlainSquare s430= new PlainSquare();
		s430.setBorder(Directions.North, new Wall());
		s430.setBorder(Directions.East, new Wall());
		s430.setBorder(Directions.South, new Wall(new Door()));
		s430.getBorderByDirection(Directions.South).getDoor().openDoor();
		PlainSquare s440= new PlainSquare();
		s440.setBorder(Directions.East, new Wall());
		PlainSquare s450= new PlainSquare();
		s450.setBorder(Directions.East, new Wall());
		PlainSquare s350= new PlainSquare();
		PlainSquare s610= new PlainSquare();
		PlainSquare s880 = new PlainSquare();
		s610.setBorder(Directions.West, new Wall());
		s610.setBorder(Directions.East, new Wall());
		s610.setBorder(Directions.South, new Wall(new Door()));
		s610.getBorderByDirection(Directions.South).getDoor().openDoor();
		PlainSquare s620= new PlainSquare();
		s620.setBorder(Directions.West, new Wall());
		s110.setTemperature(10, Temperature.CELCIUS);
		s110.setHumidity(new BigDecimal("0.3"));
		s120.setHumidity(new BigDecimal("0.2"));
		s120.setTemperature(10, Temperature.CELCIUS);
		s130.setTemperature(10, Temperature.CELCIUS);
		s130.setMaterial(false);
		s150.setMaterial(false);
		s220.setMaterial(false);
		s230.setMaterial(false);
		s240.setMaterial(false);
		s250.setMaterial(false);
		s330.setMaterial(false);
		s340.setMaterial(false);
		s430.setMaterial(false);
		s440.setMaterial(false);
		s450.setMaterial(false);
		s350.setMaterial(false);
		s610.setTemperature(10, Temperature.CELCIUS);
		s620.setTemperature(20, Temperature.CELCIUS);
		s880.setTemperature(30, Temperature.CELCIUS);
		s880.setMaterial(false);
		
		try {
			Level.addSquareToDungeon(1, 1, 8, s110);
			Level.addSquareToDungeon(1, 2, 8, s120);
			Level.addSquareToDungeon(1, 3, 8, s130);
			Level.addSquareToDungeon(1, 5, 8, s150);
			Level.addSquareToDungeon(2, 2, 8, s220);
			Level.addSquareToDungeon(2, 3, 8, s230);
			Level.addSquareToDungeon(2, 4, 8, s240);
			Level.addSquareToDungeon(2, 5, 8, s250);
			Level.addSquareToDungeon(3, 3, 8, s330);
			Level.addSquareToDungeon(3, 4, 8, s340);
			Level.addSquareToDungeon(4, 3, 8, s430);
			Level.addSquareToDungeon(4, 4, 8, s440);
			Level.addSquareToDungeon(4, 5, 8, s450);
			Level.addSquareToDungeon(3, 5, 8, s350);
			
			Level.addSquareToDungeon(6, 2, 8, s620);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertFalse(Level.isReachableInTheSameSpace(s150, s110));
		assertTrue(Level.getSquareAt(1, 5, 8).hasBorder(Directions.East));
		Level.removeBorderFromSquareInDungeon(s150, Directions.East);
		assertTrue(Level.isReachable(s150, s110));
		
	}

		@Test
		public final void reachabilityTest(){
			PlainSquare s110 = new PlainSquare();
			PlainSquare s120 = new PlainSquare();
			s120.setBorder(Directions.South, new Wall());
			PlainSquare s130= new PlainSquare();
			s130.setBorder(Directions.South, new Wall());
			s130.setBorder(Directions.East, new Wall());
			PlainSquare s150= new PlainSquare();
			s150.setBorder(Directions.North, new Wall());
			s150.setBorder(Directions.East, new Wall());
			
			assertTrue(s150.hasBorder(Directions.East));
			
			PlainSquare s220= new PlainSquare();
			s220.setBorder(Directions.North, new Wall());
			s220.setBorder(Directions.East, new Wall(new Door()));
			s220.getBorderByDirection(Directions.East).getDoor().openDoor();
			assertTrue(s220.getBorderByDirection(Directions.East).hasDoor());
			PlainSquare s230= new PlainSquare();
			PlainSquare s240= new PlainSquare();
			PlainSquare s250= new PlainSquare();
			s250.setBorder(Directions.East, new Wall());
			PlainSquare s330= new PlainSquare();
			PlainSquare s340= new PlainSquare();
			s340.setBorder(Directions.East, new Wall());
			s340.setBorder(Directions.South, new Wall());
			PlainSquare s430= new PlainSquare();
			s430.setBorder(Directions.North, new Wall());
			s430.setBorder(Directions.East, new Wall());
			s430.setBorder(Directions.South, new Wall(new Door()));
			s430.getBorderByDirection(Directions.South).getDoor().openDoor();
			PlainSquare s440= new PlainSquare();
			s440.setBorder(Directions.East, new Wall());
			PlainSquare s450= new PlainSquare();
			s450.setBorder(Directions.East, new Wall());
			PlainSquare s350= new PlainSquare();
			PlainSquare s610= new PlainSquare();
			PlainSquare s880 = new PlainSquare();
			s610.setBorder(Directions.West, new Wall());
			s610.setBorder(Directions.East, new Wall());
			s610.setBorder(Directions.South, new Wall(new Door()));
			s610.getBorderByDirection(Directions.South).getDoor().openDoor();
			PlainSquare s620= new PlainSquare();
			s620.setBorder(Directions.West, new Wall());
			s110.setTemperature(10, Temperature.CELCIUS);
			s110.setMaterial(false);
			s110.setHumidity(new BigDecimal("0.3"));
			s120.setHumidity(new BigDecimal("0.2"));
			s120.setTemperature(10, Temperature.CELCIUS);
			s130.setTemperature(10, Temperature.CELCIUS);
			s130.setMaterial(false);
			s120.setMaterial(false);
			s150.setMaterial(false);
			s220.setMaterial(false);
			s230.setMaterial(false);
			s240.setMaterial(false);
			s250.setMaterial(false);
			s330.setMaterial(false);
			s340.setMaterial(false);
			s430.setMaterial(false);
			s440.setMaterial(false);
			s450.setMaterial(false);
			s350.setMaterial(false);
			s610.setTemperature(10, Temperature.CELCIUS);
			s620.setTemperature(20, Temperature.CELCIUS);
			s880.setTemperature(30, Temperature.CELCIUS);
			s880.setMaterial(false);
			
			assertTrue(Level.canHaveAsSquare(s110));
			try {
				Level.addSquareToDungeon(1, 1, 8, s110);
				Level.addSquareToDungeon(1, 2, 8, s120);
				Level.addSquareToDungeon(1, 3, 8, s130);
				Level.addSquareToDungeon(1, 5, 8, s150);
				Level.addSquareToDungeon(2, 2, 8, s220);
				Level.addSquareToDungeon(2, 3, 8, s230);
				Level.addSquareToDungeon(2, 4, 8, s240);
				Level.addSquareToDungeon(2, 5, 8, s250);
				Level.addSquareToDungeon(3, 3, 8, s330);
				Level.addSquareToDungeon(3, 4, 8, s340);
				Level.addSquareToDungeon(4, 3, 8, s430);
				Level.addSquareToDungeon(4, 4, 8, s440);
				Level.addSquareToDungeon(4, 5, 8, s450);
				Level.addSquareToDungeon(3, 5, 8, s350);
				
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
			assertFalse(Level.isReachableInTheSameSpace(s150, s110));
			assertTrue(Level.getSquareAt(1, 5, 8).hasBorder(Directions.East));
			Level.removeBorderFromSquareInDungeon(s150, Directions.East);
			assertTrue(Level.isReachable(s150, s110));
			
	
			
			
	}
	
			
		
	@Test
	public final void getXetcCoordinatesInArray(){
		long[] array1 = Level.getxyAndzCoordinate(Level.getSquareAt(1, 8, 8));
		long[] array = new long[3];
		array[0] = 0;
		array[1] = 1;
		array[2] = 2;
		assertEquals(array1[0], 1);
	}
	
	@Test
	public final void testForAdjustmentRockSquareTemperature() throws IllegalDimensionException{
		Level<SquareImp> newLevel = new Level<SquareImp>(100,100,100,0);
		RockSquare rock = new RockSquare();
		rock.setMaterial(false);
		assertTrue(rock.isValidTemperature(69));
		rock.setTemperature(69, Temperature.CELCIUS);
		
		PlainSquare normalSquare = new PlainSquare();
		normalSquare.setMaterial(false);
		normalSquare.setTemperature(50, Temperature.CELCIUS);
		
		PlainSquare otherSquare = new PlainSquare(20, new BigDecimal("0.3"), null);
		otherSquare.setMaterial(false);
		
		try {
			newLevel.addSquareToDungeon(10, 20, 0, rock);
			newLevel.addSquareToDungeon(10, 21, 0, otherSquare);
			newLevel.addSquareToDungeon(10, 19, 0, normalSquare);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		assertEquals(rock, newLevel.getSquareAt(10, 20,0));
		assertEquals(otherSquare, newLevel.getSquareAt(10, 21, 0));
		assertEquals(normalSquare, newLevel.getSquareAt(10, 19, 0));
		
		assertEquals(newLevel.getSquareAt(10, 20, 0).getTemperature(), 35,0);
		assertEquals(newLevel.getSquareAt(10, 19, 0).getTemperature(), 50,0);
		assertEquals(newLevel.getSquareAt(10, 21,0).getTemperature(), 20,0);
		
	}
	
	@Test	
	public final void TransparantFirstCaseTest() throws IllegalDimensionException{
		Level<SquareImp> myLevel = new Level<SquareImp>(10,20,40,4);
			
			RockSquare rock = new RockSquare();
			rock.setBorder(Directions.South, new Wall());
			rock.setMaterial(false);
			
			TransparantSquare trans = new TransparantSquare();
			trans.setMaterial(false);
			
			try {
				myLevel.addSquareToDungeon(1, 2, 4, trans);
			} catch (Exception e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			}
			
			assertFalse(myLevel.canHaveAsSquareAtCoordinate(1, 1, 4, rock));
			
			
			
	}
	
	@Test	
	public final void TransparantSecondCaseTest() throws IllegalDimensionException{
		Level<SquareImp> myLevel = new Level<SquareImp>(10,20,40,4);
			new Door();
			TransparantSquare transp = new TransparantSquare();
			transp.setMaterial(false);
			
			RockSquare rock = new RockSquare();
			rock.setBorder(Directions.South, new Wall());
			rock.setMaterial(false);
				
			try {			
				myLevel.addSquareToDungeon(1, 2, 4, rock);
			} catch (Exception e) {
			e.printStackTrace();
			}	
			
			assertFalse(myLevel.canHaveAsSquareAtCoordinate(1, 1, 4, transp));
			
			
			
	}
	@Test	
	public final void TransparantThrid_OnecaseTest() throws IllegalDimensionException{
		Level<SquareImp> myLevel = new Level<SquareImp>(10,20,40,3);
		
		TransparantSquare trans1 = new TransparantSquare();
		TransparantSquare trans2 = new TransparantSquare();
		
		trans1.setMaterial(false);
		trans2.setMaterial(false);
		
		try {
			myLevel.addSquareToDungeon(1, 2, 3, trans1);
		} catch (Exception e) {
			e.printStackTrace();
		}
		try {
			myLevel.addSquareToDungeon(1, 3, 3, trans2);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	assertEquals(trans2.getBorderByDirection(Directions.North), trans1.getBorderByDirection(Directions.South));

	
	}
		@Test	
	public final void TransparantThrid_TwocaseTest() throws IllegalDimensionException{
			Level<SquareImp> myLevel = new Level<SquareImp>(10,20,40,3);
		
		TransparantSquare trans1 = new TransparantSquare();
		TransparantSquare trans2 = new TransparantSquare(Directions.East);
		
		
		trans1.setMaterial(false);
		trans2.setMaterial(false);
		
		try {
			myLevel.addSquareToDungeon(1, 2, 3, trans2);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertFalse(myLevel.canHaveAsSquareAtCoordinate(1, 3, 3, trans1));
		
	}
	
	
		
		
	
	
	@Test	
	public final void TransparantFifth_OneCaseTest() throws IllegalDimensionException{
		Level<SquareImp> myLevel = new Level<SquareImp>(10,20,40,3);
		
		TransparantSquare square = new TransparantSquare();
		PlainSquare neigboor = new PlainSquare();
		
		square.setMaterial(false);
		neigboor.setMaterial(false);
		
		try {
			myLevel.addSquareToDungeon(1, 2, 3, neigboor);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			myLevel.addSquareToDungeon(1, 3, 3, square);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertEquals(square.getBorderByDirection(Directions.North), neigboor.getBorderByDirection(Directions.South));
	}
	
	@Test	
	public final void TransparantFifth_TwoCaseTest() throws IllegalDimensionException{
		Level<SquareImp> myLevel = new Level<SquareImp>(10,20,40,3);
		
		TransparantSquare square = new TransparantSquare();
		PlainSquare neigboor = new PlainSquare();
		Wall wall1 = new Wall(new Door());
		Wall wall2 = new Wall(new Door());
		Wall wall3 = new Wall(new Door());
		
		
		neigboor.setBorder(Directions.East, wall1);
		neigboor.setBorder(Directions.West, wall2);
		neigboor.setBorder(Directions.Ceiling, wall3);
		
		square.setMaterial(false);
		neigboor.setMaterial(false);
		
		try {
			myLevel.addSquareToDungeon(1, 2, 3, neigboor);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		assertFalse(myLevel.canHaveAsSquareAtCoordinate(1, 3, 3, square));
		
		
		
	}
	
	@Test	
	public final void TransparantSixth_OneCaseTest() throws IllegalDimensionException{
		Level<SquareImp> myLevel = new Level<SquareImp>(10,20,40,2);
		
		PlainSquare square = new PlainSquare();
		square.setMaterial(false);
		square.setBorder(Directions.North, new Wall(new Door()));
		
		
		TransparantSquare neigboor = new TransparantSquare();
		neigboor.setMaterial(false);
		
		try {
			myLevel.addSquareToDungeon(0, 0, 2, neigboor);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			myLevel.addSquareToDungeon(0, 1, 2, square);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertEquals(neigboor.getBorderByDirection(Directions.South), square.getBorderByDirection(Directions.North));
		
	}
	
	@Test	
	public final void TransparantSixth_TwoCaseTest() throws IllegalDimensionException{
		Level<SquareImp> myLevel = new Level<SquareImp>(10,20,40,2);
		
		PlainSquare square = new PlainSquare();
		square.setMaterial(false);
		square.setBorder(Directions.North, new Wall());		
		TransparantSquare neigboor = new TransparantSquare();
		neigboor.setMaterial(false);
		
		try {
			myLevel.addSquareToDungeon(0, 0, 2, neigboor);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertFalse(myLevel.canHaveAsSquareAtCoordinate(0, 1, 2, square));
		
		
		
	}
	
	@Test
	public final void reachabilityTest1() throws IllegalDimensionException{
		Level<SquareImp> myLevel = new Level<SquareImp>(100,100,100,0);
		new Level<SquareImp>(100,100,100,0);
		
		ArrayList<SquareImp> translist = new ArrayList<SquareImp>(0);
		
		ArrayList<SquareImp> plainlist = new ArrayList<SquareImp>(0);
		
		PlainSquare s010 = new PlainSquare();
		PlainSquare s020 = new PlainSquare();
		TeleportTransparantSquare s030 = new TeleportTransparantSquare(translist);
		TeleportPlainSquare s040 = new TeleportPlainSquare(plainlist);
		PlainSquare s050 = new PlainSquare();
		
		
		s010.setMaterial(false);
		s020.setMaterial(false);
		s030.setMaterial(false);
		s040.setMaterial(false);
		s050.setMaterial(false);
			
		
		try {
			myLevel.addSquareToDungeon(0, 1, 0, s010);
			myLevel.addSquareToDungeon(0, 2, 0, s020);
			myLevel.addSquareToDungeon(0, 3, 0, s030);
			myLevel.addSquareToDungeon(0, 4, 0, s040);
			myLevel.addSquareToDungeon(0, 5, 0, s050);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedOperationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		assertTrue(myLevel.isReachable(s010, s020));
		assertFalse(myLevel.isReachable(s010, s050));
		
		
		assertFalse(myLevel.isReachable(s030, s020));
		translist.add(s020);
		assertTrue(myLevel.isReachable(s030, s020));
		
		
		assertTrue(myLevel.isReachable(s040, s010));

		
		
	}
	
	@Test
	public final void reachabilityTestSquareinAnotherLevel() throws IllegalDimensionException{
		Level<SquareImp> myLevel = new Level<SquareImp>(100,100,100,0);
		Level<SquareImp> otherLevel = new Level<SquareImp>(100,50,100,0);
		
		ArrayList<SquareImp> translist = new ArrayList<SquareImp>(0);
		
		ArrayList<SquareImp> plainlist = new ArrayList<SquareImp>(0);
		
		PlainSquare s010 = new PlainSquare();
		PlainSquare s020 = new PlainSquare();
		TeleportTransparantSquare s030 = new TeleportTransparantSquare(translist);
		TeleportPlainSquare s040 = new TeleportPlainSquare(plainlist);
		PlainSquare s050 = new PlainSquare();
		
		PlainSquare s110 = new PlainSquare();
		s110.setMaterial(false);
		
		
		s010.setMaterial(false);
		s020.setMaterial(false);
		s030.setMaterial(false);
		s040.setMaterial(false);
		s050.setMaterial(false);
			
		
		try {
			myLevel.addSquareToDungeon(0, 1, 0, s010);
			myLevel.addSquareToDungeon(0, 2, 0, s020);
			myLevel.addSquareToDungeon(0, 3, 0, s030);
			myLevel.addSquareToDungeon(0, 4, 0, s040);
			myLevel.addSquareToDungeon(0, 5, 0, s050);
			
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedOperationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		try {
			otherLevel.addSquareToDungeon(1, 1, 0, s110);
		} catch (IllegalArgumentException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (UnsupportedOperationException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch(IllegalDimensionException e){
			e.printStackTrace();
		}
		
		assertTrue(otherLevel.hasSquareAt(1, 1, 0));
		
		assertTrue(myLevel.isReachable(s050, s040));
		assertFalse((myLevel.isReachable(s050, s010)));
		
		assertFalse(myLevel.isReachable(s050, s110));
		assertTrue(myLevel.isReachable(s050, s030	));
		translist.add(s110);
		assertTrue(myLevel.isReachable(s050, s030));
		assertTrue(myLevel.isReachable(s030, s110));
		
		myLevel.isReachable(s050, s110);
		assertTrue(myLevel.isReachable(s050, s110));
		
		translist.remove(s110);
		assertTrue(myLevel.isReachable(s050, s040));
		assertFalse(myLevel.isReachable(s040, s110));
		plainlist.add(s110);
		assertTrue(myLevel.isReachable(s040, s110));
		assertTrue(myLevel.isReachable(s050, s110));
		assertTrue(myLevel.isReachable(s050, s110));
		plainlist.remove(s110);
		assertFalse(myLevel.isReachable(s050, s110));
		
	}	
	
	
}

	
		
		
	

	
	

